import { Request, Response } from 'express';
import { MongoClient } from 'mongodb';
import { isNaggetContent, Nagget } from '../models/nagget';
import { Collections } from '../objects/Collections';

const MALFORMED_REQUEST = 'guetctf{g4rb4g3_1n_g4rb4g3_0u7}';

export class WriteRoute {
	constructor(mongo: MongoClient) {
		this.mongo = mongo;
	}

	public async write(req: Request, res: Response) {
		// token check shall be done before this!
		const input = req.body['post'];
		let content;
		if (typeof(input) == 'string') {
			try {
				content = JSON.parse(input);
			} catch (e) {
				res.status(400);
				res.send({
					reason: 'not a valid json object'
				});
				return;
			}
		} else if (typeof(input) == 'object') {
			content = input;
		} else {
			res.status(400);
			res.send({
				reason: MALFORMED_REQUEST
			});
			return;
		}
		if (!content.hasOwnProperty('postTime')) {
			content['postTime'] = new Date();
		} else {
			if (typeof content['postTime'] == 'string') {
				content['postTime'] = new Date(content['postTime']);
			} else {
				res.status(400);
				res.send({
					reason: MALFORMED_REQUEST
				});
				return;
			}
		}
		if (!content.hasOwnProperty('content')) {
			res.status(400);
			res.send({
				reason: 'empty post not allowed'
			});
			return;
		}
		if (!content.hasOwnProperty('username')) {
			res.status(400);
			res.send({
				reason: 'anonymous post not allowed'
			});
			return;
		}
		// test if content has a correct structure
		if (typeof content.content == 'string') {
			// dumb text
			content.content = [
				{
					type: 'text',
					content: content.content
				}
			];
			await this.mongo.db().collection<Nagget>(Collections.NAGGETS).insertOne(content);
		} else if (typeof content.content == 'object') {
			if (content.content instanceof Array) {
				// the good, correct one
				for (let item of content.content) {
					if (!isNaggetContent(item)) {
						res.status(400);
						res.send({
							reason: 'malformed content'
						});
						return;
					}
				}
				// oll korrect
				await this.mongo.db().collection<Nagget>(Collections.NAGGETS).insertOne(content);
			} else {
				// single object?
				if (isNaggetContent(content.content)) {
					content.content = [ content.content ];
					await this.mongo.db().collection<Nagget>(Collections.NAGGETS).insertOne(content);
				} else {
					res.status(400);
					res.send({
						reason: 'malformed single object content'
					});
					return;
				}
			}
		}
		res.send({
			code: 0
		});
	}

	private mongo: MongoClient;
}
